package com.qipay.sp.impl;

import com.qipay.baas.model.Sp;
import com.qipay.baas.model.SpExample;
import com.qipay.core.entity.Pagination;
import com.qipay.core.utils.CommUtil;
import com.qipay.core.utils.SpringContextUtil;
import com.qipay.mapper.SpMapper;
import com.qipay.sp.SpService;
import com.qipay.sp.SpUserService;
import com.qipay.sp.excutor.ExcutorFactory;
import io.jsonwebtoken.lang.Assert;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class SpServiceImpl implements SpService {

    @Autowired
    SpMapper spMapper;

    @Autowired
    SpUserService spUserService;

    @Override
    @Transactional
    public int insert(Sp sp) {
        return spMapper.insert(sp);
    }

    @Override
    @Transactional
    public int update(Sp sp) {
        return spMapper.updateByPrimaryKey(sp);
    }

    @Override
    @Transactional
    public int delete(int id) {
        return spMapper.deleteByPrimaryKey((long) id);
    }

    @Override
    public Sp get(int id) {
        return spMapper.selectByPrimaryKey((long) id);
    }

    @Override
    public List<Sp> all() {
        return spMapper.selectAll();
    }

    @Override
    public ExcutorFactory getFactory(Long spid)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Sp sp = spMapper.selectByPrimaryKey(spid);
        return getFactory(sp);
    }

    @Override
    public ExcutorFactory getFactory(Sp sp)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        ExcutorFactory excutorFactory =
                (ExcutorFactory) SpringContextUtil.getBean(Class.forName(sp.getFactoryClassName()));
        return excutorFactory;
    }

    @Override
    @Transactional
    public int updateState(int id, byte state) {
        Sp sp = new Sp();
        sp.setId((long) id);
        sp.setState(state);
        sp.setFailReason(null);
        return spMapper.updateState(sp);
    }

    @Override
    @Transactional
    public int updateDeleteFlag(int id) {
        Sp sp = new Sp();
        sp.setId((long) id);
        sp.setDeleteFlag((byte) 1);
        return spMapper.updateByPrimaryKeySelective(sp);
    }

    @Override
    public List<Sp> getByCondition(String name, String service, String bank, Byte state, int p, int pz, String spUserName) {
        p = p <= 0 ? 1 : p;
        pz = pz <= 0 ? 10 : pz;
        Map<String, Object> mapList = buildConditionMap(name, service, bank, state,spUserName);
        mapList.put("offset", (p - 1) * pz);
        mapList.put("size", pz);
        List<Sp> sps = spMapper.selectByCondition(mapList);
        if (CommUtil.isNotEmpty(sps)) {
            //取出name
            List<String> collect = sps.stream().filter(s -> CommUtil.isNotEmpty(s.getSpUserName()))
                    .map(s -> s.getSpUserName()).collect(Collectors.toList());
            Map<String, String> stringStringMap = spUserService.selectSPUserName(collect);

            sps = sps.stream().map(s -> {
                s.setSpUserName(Optional.ofNullable(stringStringMap.get(s.getSpUserName())).orElse(""));
                return s;
            }).collect(Collectors.toList());
        }
        return sps;
    }

    @Override
    public long countByCondition(String name, String service, String bank, Byte state, String spUserName) {
        Map<String, Object> mapList = buildConditionMap(name, service, bank, state, spUserName);
        return spMapper.countByCondition(mapList);
    }

    @Override
    public List<Sp> findByIdIn(List<Long> list) {

        // check
        Assert.isTrue(CollectionUtils.isNotEmpty(list));

        return spMapper.findByIdIn(list, "");
    }

    @Override
    public List<Sp> findBySpUser(String userName, Pagination pagination) {
        if (CommUtil.isEmpty(userName)) {
            throw new RuntimeException("userName不能为空");
        }

        SpExample spExample = new SpExample();
        spExample.or().andSpUserNameEqualTo(userName);
        spExample.setOrderByClause("id desc");

        //启用分页后调用
        List<Sp> sps = Pagination.wrapper(() -> spMapper.selectByExample(spExample), pagination);
        return sps;
    }

    Map<String, Object> buildConditionMap(String name, String service, String bank, Byte state, String spUserName) {
        Map<String, Object> mapList = new HashMap<>(4);


        if (StringUtils.isNotEmpty((name))) {
            mapList.put("name", name);
        }
        if (StringUtils.isNotEmpty((service))) {
            mapList.put("service", service);
        }
        if (StringUtils.isNotEmpty((bank))) {
            mapList.put("bank", bank);
        }
        if (state != null) {
            mapList.put("state", state);
        }
        if (CommUtil.isNotEmpty(spUserName)) {
            mapList.put("sp_user_name", spUserName);
        }
        return mapList;
    }
}
